﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using Qy.Core;
using Qy.Scenario;
using System;
using System.Linq;
using System.Text.Encodings.Web;
using System.Text.Json;

namespace Qy.Web.Authorize.Common;
public class GlobalActionMonitor : ActionFilterAttribute
{
    private readonly LogService _logService;
    public GlobalActionMonitor(LogService logService)
    {
        _logService = logService;
    }

    /// <summary>
    /// 日志记录
    /// OnResultExecuted是在Action中的代码执行之后运行的方法。
    /// OnActionExecuting在action method调用前发生。
    /// OnActionExecuted在action method调用后发生, 但是在result执行前发生 (在 view 呈现前)
    /// OnResultExecuting在result执行前发生(在view 呈现前)
    /// OnResultExecuted 在result执行后发生(在view 呈现后)
    /// </summary>
    /// <param name="context"></param>
    public override void OnResultExecuted(ResultExecutedContext context)
    {
        if (context.ActionDescriptor is not ControllerActionDescriptor controllerActionDescriptor) return;
        //获得注解信息，如果没有注解返回，不执行记录
        LogAttribute logAttribute = GetLogAttribute(controllerActionDescriptor);
        if (logAttribute == null) return;
        try
        {
            //string method = context.HttpContext.Request.Method.ToUpper(); //POST  GET  ...
            string jsonResult = string.Empty;
            //if (context.Result is ContentResult result && result.ContentType == "application/json")
            //{
            //    jsonResult = result.Content.Replace("\r\n", "").Trim();
            //    Console.WriteLine(jsonResult);
            //}
            if (context.Result is JsonResult result2)
            {
                var options = new JsonSerializerOptions
                {
                    Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
                    WriteIndented = true
                };
                jsonResult = JsonSerializer.Serialize(result2.Value, options);
            }
            LogSql logSql = new()
            {
                UserId = App.HttpContext.GetUId(),
                Name = logAttribute.Name,
                DoThing = jsonResult,
                ControllerAction = App.HttpContext.GetController() + "/" + App.HttpContext.GetAction(),
                Ip = App.HttpContext.GetClientUserIp(),
                Time = DateTime.Now
            };
            _logService.InsertLogAsync(logSql);
        }
        catch (Exception ex)
        {
            Console.WriteLine("记录用户行为日志出错:" + ex.Message);
        }
    }

    private static LogAttribute GetLogAttribute(ControllerActionDescriptor controllerActionDescriptor)
    {
        var attribute = controllerActionDescriptor.MethodInfo.GetCustomAttributes(inherit: true)
            .FirstOrDefault(a => a.GetType().Equals(typeof(LogAttribute)));
        return attribute as LogAttribute;
    }
}
